package com.oauth.filter;

import com.oauth.utils.CustomHttpServletRequest;
import org.apache.tomcat.util.http.MimeHeaders;
import org.springframework.security.authentication.AnonymousAuthenticationToken;
import org.springframework.security.core.Authentication;
import org.springframework.security.core.GrantedAuthority;
import org.springframework.security.core.context.SecurityContextHolder;
import org.springframework.security.oauth2.provider.OAuth2Authentication;
import org.springframework.util.AntPathMatcher;
import org.springframework.util.Base64Utils;
import org.springframework.util.LinkedMultiValueMap;
import org.springframework.util.MultiValueMap;

import javax.servlet.*;
import javax.servlet.http.HttpServletRequest;
import java.io.File;
import java.io.IOException;
import java.lang.reflect.Field;
import java.util.*;

public class LoginFilter implements Filter {
    private AntPathMatcher matcher = null;
    @Override
    public void init(FilterConfig filterConfig) throws ServletException {
         matcher=new AntPathMatcher();
    }

    @Override
    public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain filterChain) throws IOException, ServletException {
        HttpServletRequest request=(HttpServletRequest) servletRequest;
        String requestURI = request.getRequestURI();
        if(!matcher.match("/oauth/token",requestURI)){
            Authentication authentication = SecurityContextHolder.getContext().getAuthentication();
            if (authentication instanceof AnonymousAuthenticationToken) {

            }
            //OAuth2A加密时，添加了userid，roles，校验时取出来，，加密设置服务校验token
            if (authentication instanceof OAuth2Authentication) {
                OAuth2Authentication oauth2Authentication = (OAuth2Authentication) authentication;
                String userid = String.valueOf(oauth2Authentication.getPrincipal());
                List<String> roles = new ArrayList<String>();
                for (GrantedAuthority granted : oauth2Authentication.getAuthorities()) {
                    roles.add(granted.getAuthority());
                }
            }
        }
        filterChain.doFilter(request,servletResponse);
    }

    /**
     * 添加请求头
     * @param request
     * @param headerMap
     */
    private void addHeader(HttpServletRequest request, Map<String, String> headerMap) {
        if (headerMap==null||headerMap.isEmpty()){
            return;
        }

        Class<? extends HttpServletRequest> c=request.getClass();
        //System.out.println(c.getName());
        System.out.println("request实现类="+c.getName());
        try{
            Field requestField=c.getDeclaredField("request");
            requestField.setAccessible(true);

            Object o=requestField.get(request);
            Field coyoteRequest=o.getClass().getDeclaredField("coyoteRequest");
            coyoteRequest.setAccessible(true);

            Object o2=coyoteRequest.get(o);
            System.out.println("coyoteRequest实现类="+o2.getClass().getName());
            Field headers=o2.getClass().getDeclaredField("headers");
            headers.setAccessible(true);

            MimeHeaders mimeHeaders=(MimeHeaders) headers.get(o2);
            for (Map.Entry<String,String> entry:headerMap.entrySet()){
                mimeHeaders.removeHeader(entry.getKey());
                mimeHeaders.addValue(entry.getKey()).setString(entry.getValue());
            }

        }catch (Exception e){
            e.printStackTrace();
        }

    }
    private MultiValueMap<String, String> authorizeHttpHeaders(String clientinfo,CustomHttpServletRequest request) {
        MultiValueMap<String, String> head = new LinkedMultiValueMap<String, String>();
        StringBuilder headBuilder = new StringBuilder();
        headBuilder.append("Basic").append(" ").append(clientinfo);
        request.addHeader("authorization", headBuilder.toString());
        return head;
    }

    /**
     * 设置认证头部
     *
     * @return
     */
    protected MultiValueMap<String, String> getHttpHeaders(CustomHttpServletRequest request) {
        StringBuilder clientinfo = new StringBuilder();
        clientinfo.append("client").append(":").append("112233");
        String base64Clientinfo = Base64Utils.encodeToString(clientinfo.toString().getBytes());
        return authorizeHttpHeaders(base64Clientinfo,request);
    }
    @Override
    public void destroy() {

    }
}
